import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { prisma } from '../config/database';
import config from '@/config';

// 扩展Request接口以包含用户信息
declare global {
  namespace Express {
    interface Request {
      user?: {
        id: number;
        username: string;
        email: string;
        roles: string[];
        permissions: string[];
      };
    }
  }
}

// JWT认证中间件
export const authenticate = async (
  req: Request,
  res: Response,
  next: NextFunction
): Promise<void> => {
  try {
    // 获取token
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      res.status(401).json({
        success: false,
        code: 2001,
        message: '未提供访问令牌',
        timestamp: new Date().toISOString()
      });
      return;
    }

    const token = authHeader.substring(7);

    // 验证token
    const decoded = jwt.verify(token, config.jwt.secret) as any;

    // 检查用户是否存在
    const user = await prisma.user.findUnique({
      where: { id: decoded.id },
      include: {
        userRoles: {
          include: {
            role: {
              include: {
                rolePermissions: {
                  include: {
                    permission: true
                  }
                }
              }
            }
          }
        }
      }
    });

    if (!user) {
      res.status(401).json({
        success: false,
        code: 2002,
        message: '用户不存在',
        timestamp: new Date().toISOString()
      });
      return;
    }

    if (user.status !== 'ACTIVE') {
      res.status(401).json({
        success: false,
        code: 2003,
        message: '用户账户已被禁用',
        timestamp: new Date().toISOString()
      });
      return;
    }

    // 提取用户角色和权限
    const roles = user.userRoles.map(ur => ur.role.name);
    const permissions = user.userRoles.flatMap(ur => 
      ur.role.rolePermissions.map(rp => rp.permission.code)
    );

    // 将用户信息添加到请求对象
    req.user = {
      id: user.id,
      username: user.username,
      email: user.email,
      roles,
      permissions
    };

    next();
  } catch (error) {
    if (error instanceof jwt.JsonWebTokenError) {
      res.status(401).json({
        success: false,
        code: 2004,
        message: '无效的访问令牌',
        timestamp: new Date().toISOString()
      });
    } else if (error instanceof jwt.TokenExpiredError) {
      res.status(401).json({
        success: false,
        code: 2005,
        message: '访问令牌已过期',
        timestamp: new Date().toISOString()
      });
    } else {
      res.status(500).json({
        success: false,
        code: 2006,
        message: '认证过程中发生错误',
        timestamp: new Date().toISOString()
      });
    }
  }
};

// 权限验证中间件
export const authorize = (requiredPermissions: string[]) => {
  return (req: Request, res: Response, next: NextFunction): void => {
    if (!req.user) {
      res.status(401).json({
        success: false,
        code: 2000,
        message: '用户未认证',
        timestamp: new Date().toISOString()
      });
      return;
    }

    const hasPermission = requiredPermissions.some(permission =>
      req.user!.permissions.includes(permission)
    );

    if (!hasPermission) {
      res.status(403).json({
        success: false,
        code: 3000,
        message: '权限不足',
        timestamp: new Date().toISOString()
      });
      return;
    }

    next();
  };
};

// 角色验证中间件
export const requireRole = (requiredRoles: string[]) => {
  return (req: Request, res: Response, next: NextFunction): void => {
    if (!req.user) {
      res.status(401).json({
        success: false,
        code: 2000,
        message: '用户未认证',
        timestamp: new Date().toISOString()
      });
      return;
    }

    const hasRole = requiredRoles.some(role =>
      req.user!.roles.includes(role)
    );

    if (!hasRole) {
      res.status(403).json({
        success: false,
        code: 3001,
        message: '角色权限不足',
        timestamp: new Date().toISOString()
      });
      return;
    }

    next();
  };
}; 